﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentNHibernate.Mapping;
using System.Web;
using System.Web.Mvc;
using Telerik.Web.Mvc.UI;
using System.IO;
using System.Reflection;

namespace nwrole.toolbox.sync.entity
{
    public class nhEntity 
    {
        public virtual long Id { get; set; }

        public virtual string Name { get; set; }

        public virtual int SortIndex { get; set; }

        public virtual string TableName { get; set; }

        public virtual DateTime? CreatedDate { get; set; }

        public virtual DateTime? ModifiedDate { get; set; }

        public virtual IList<nhEntityColumn> Columns { get; set; }

    }

    public class nhEntityMapping : ClassMap<nhEntity>
    {
        public nhEntityMapping()
        {
            Id(x => x.Id);
            Map(x => x.Name).Length(32).Not.Nullable();
            Map(x => x.SortIndex);
            Map(x => x.TableName);
            Map(x => x.CreatedDate);
            Map(x => x.ModifiedDate);
            HasMany(x => x.Columns).KeyColumns.Add("nhEntityId").Inverse().Cascade.All();
        }
    }

    public interface IDynComp
    {
        void RenderMe(HtmlHelper helper);
        void Test(Assembly assembly);
    }

/*    public class GridComponent : IDynComp
    {
        public void RenderMe(HtmlHelper helper)
        {
            TextWriter writer = helper.ViewContext.Writer;
            helper.Telerik()
                .Grid<object>()
                .Columns(columns =>
                {
                    columns.Template(m =>
                    {
                        writer.Write("djfhdjhf");
                    });
                })
                .Render();

        }
    } */

    public class nhClassGenerator
    {
        public static string GenerateClass1(nhEntity entity, nhEntityView view)
        {
            StringBuilder classCode = new StringBuilder();
            StringBuilder mappingCode = new StringBuilder();
            foreach (var col in entity.Columns)
            {
                classCode.Append("        public virtual ");
                classCode.Append(col.CSharpTypeName);
                classCode.Append(" ");
                classCode.Append(col.ColumnName);
                classCode.Append(" { get; set; }\r\n");

                if (1 == 1)
                {
                    mappingCode.Append("            Map(x => x.");
                    mappingCode.Append(col.ColumnName);
                    mappingCode.Append(")");
                    if (col.CSharpLength.HasValue)
                    {
                        mappingCode.AppendFormat(".Length({0})", col.CSharpLength.Value);
                    }
                    if (col.Nullable)
                    {
                        mappingCode.Append(".Nullable()");
                    }
                    else
                    {
                        mappingCode.Append(".Not.Nullable()");
                    }
                    if (!string.IsNullOrEmpty(col.nhReferences)) 
                    {
                        mappingCode.AppendFormat(".References(x => x.{0})", col.nhReferences);
                    }
                    if (!string.IsNullOrEmpty(col.nhHasMany))
                    {
                        mappingCode.AppendFormat(".HasMany(x => x.{0}).Inverse().Cascade.All()", col.nhHasMany);
                    }
                    mappingCode.Append(";\r\n");
                }
            }

            string namespaceStr = "mynamespace";
            string className = entity.Name;

            string code = classTemplate1
                .Replace("{namespace}", namespaceStr)
                .Replace("{className}", className)
                .Replace("{classCode}", classCode.ToString())
                .Replace("{classMapping}", mappingCode.ToString())
                .Replace("{telerikCode}", GenerateComponent(view, "jhjhj"));

            return code;
        }

        public static string GenerateClass2(nhEntity entity, nhEntityView view)
        {

            string namespaceStr = "mynamespace";
            string className = entity.Name;

            string code = classTemplate2
                .Replace("{namespace}", namespaceStr)
                .Replace("{className}", className)
                .Replace("{telerikCode}", GenerateComponent(view, "jhjhj"));

            return code;
        }

        #region component
        public static string GenerateComponent(nhEntityView view, string className)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("\t\tvar connectionString = \"Data Source=146.66.234.53;Initial Catalog=nwrole;User Id=nwrole_user;Password=nwrole123!_\";");
            sb.AppendLine("\t\tvar rep = new MyRepository();");
            sb.AppendLine("\t\tvar sessionFactory = rep.CreateSessionFactory(connectionString);");
            sb.AppendLine("\t\tvar session = sessionFactory.OpenSession();");
            sb.AppendLine("\t\tvar data = rep.LoadList(session);");

            sb.AppendFormat("\t\thelper.Telerik().Grid(data)\r\n");
            sb.AppendFormat("\t\t.Name(\"{0}\")\r\n", view.Name);
            if (view.Columns.Any())
            {
                sb.Append("\t\t.Columns(columns => {\r\n");
                foreach (var column in view.Columns)
                {
                    if (column.BindingType == nhEntityViewColumn.BindingTypeEnum.Bound)
                    {
                        sb.Append(string.Format("\r\n\t\tcolumns.Bound(k => k.{0})", column.Name));
                        if (!string.IsNullOrEmpty(column.Title))
                        {
                            sb.Append(string.Format("\r\n\t\t.Title(\"{0}\")", column.Title));
                        }
                        if (!string.IsNullOrEmpty(column.HtmlAttributes))
                        {
                            sb.Append("\r\n\t\t.HtmlAttributes(new { {0} })\r\n".Replace("{0}", column.HtmlAttributes));
                        }
                        sb.Append(";\r\n");
                    }
/*                    else if (column.BindingType == nhEntityViewColumn.BindingTypeEnum.Template)
                    {
                        sb.Append(string.Format("columns.Template({0})\r\n", column.Template));
                        if (!string.IsNullOrEmpty(column.Title))
                        {
                            sb.Append(string.Format(".Title(\"{0}\")\r\n", column.Title));
                        }
                        if (!string.IsNullOrEmpty(column.HtmlAttributes))
                        {
                            sb.Append(".HtmlAttributes(new { {0} })\r\n".Replace("{0}", column.HtmlAttributes));
                        }
                        sb.Append(";\r\n");
                    } */
                }
                sb.Append("         })\r\n");
                sb.Append("         .Render(); \r\n");

            }

            return sb.ToString();
        }



        #endregion

        public static string classTemplate1 = @"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentNHibernate.Mapping;
using nwrole.toolbox.sync.entity;
using NHibernate;
using NHibernate.Linq;
using FluentNHibernate.Cfg.Db;
using FluentNHibernate.Cfg;
using System.Web.Mvc;
using Telerik.Web.Mvc.UI;
using System.IO;

namespace {namespace}
{
    public class {className} 
    {
        {classCode}
    }

    public class {className}Mapping : ClassMap<{className}>
    {
        public {className}Mapping()
        {
            Id(x => x.Id);
            {classMapping}
        }
    }
}
";

        public static string classTemplate2 = @"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentNHibernate.Mapping;
using nwrole.toolbox.sync.entity;
using NHibernate;
using NHibernate.Linq;
using FluentNHibernate.Cfg.Db;
using FluentNHibernate.Cfg;
using System.Web.Mvc;
using Telerik.Web.Mvc.UI;
using System.IO;
using System.Reflection;
using {namespace};

namespace {namespace}2
{
    public class MyRepository {

        public ISessionFactory CreateSessionFactory(string connectionString, Assembly assembly) 
        {
            FluentConfiguration conf = Fluently.Configure()
                .Database(MsSqlConfiguration.MsSql2008.ConnectionString(connectionString).ShowSql().AdoNetBatchSize(0))
                .Mappings(m =>
                    m.FluentMappings.Add<{className}Mapping>());
                conf.BuildConfiguration().AddAssembly(assembly);
            return conf.BuildSessionFactory();
        }

        public IQueryable<{className}> LoadList(ISession session) {
            IQueryable<{className}> result = session.Query<{className}>();
            return result;
        }
    }

    public class GridComponent1 : IDynComp
    {
        public void Test(Assembly assembly) {
            var connectionString = ""Data Source=146.66.234.53;Initial Catalog=nwrole;User Id=nwrole_user;Password=nwrole123!_"";
            var rep = new MyRepository();
            var sessionFactory = rep.CreateSessionFactory(connectionString, assembly);
            var session = sessionFactory.OpenSession();
            var data = rep.LoadList(session);
 
        }

        public void RenderMe(HtmlHelper helper)
        {
            TextWriter writer = helper.ViewContext.Writer;
// telerikCode
        }
    }
}
";
    
    }
}
